/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "zobjects_stdtypes.h"

#include "list.h"

struct ListNode
{
	struct ZlangObject	*member ;
	struct list_head	node ;
} ;

struct ZlangDirectProperty_list_node
{
	struct ZlangDirectProperty_list	*list_direct_prop ;
	
	struct ListNode			*prev_list_node ;
	struct ListNode			*curr_list_node ;
	struct ListNode			*next_list_node ;
} ;

struct ZlangDirectProperty_list
{
	struct list_head		list ;
	
	int32_t				list_length ;
} ;

ZlangDirectFunction_list_node_TravelNext list_node_TravelNext;
int list_node_TravelNext( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	if( list_node_direct_prop->curr_list_node == NULL )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return 2;
	}
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "before list_node_TravelNext , prev[%p] curr[%p] next[%p]" , list_node_direct_prop->prev_list_node , list_node_direct_prop->curr_list_node , list_node_direct_prop->next_list_node )
	list_node_direct_prop->prev_list_node = list_node_direct_prop->curr_list_node ;
	list_node_direct_prop->curr_list_node = list_node_direct_prop->next_list_node ;
	list_node_direct_prop->next_list_node = list_next_entry_or_null( list_node_direct_prop->curr_list_node , & (list_node_direct_prop->list_direct_prop->list) , struct ListNode , node ) ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "after list_node_TravelNext , prev[%p] curr[%p] next[%p]" , list_node_direct_prop->prev_list_node , list_node_direct_prop->curr_list_node , list_node_direct_prop->next_list_node )
	
	if( list_node_direct_prop->curr_list_node == NULL )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return 1;
	}
	
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_node_TravelNext;
int ZlangInvokeFunction_list_node_TravelNext( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = list_node_TravelNext( rt , obj ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_list_node_TravelPrev list_node_TravelPrev;
int list_node_TravelPrev( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	if( list_node_direct_prop->curr_list_node == NULL )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return 2;
	}
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "before ZlangInvokeFunction_list_node_TravelPrev , prev[%p] curr[%p] next[%p]" , list_node_direct_prop->prev_list_node , list_node_direct_prop->curr_list_node , list_node_direct_prop->next_list_node )
	list_node_direct_prop->next_list_node = list_node_direct_prop->curr_list_node ;
	list_node_direct_prop->curr_list_node = list_node_direct_prop->prev_list_node ;
	list_node_direct_prop->prev_list_node = list_prev_entry_or_null( list_node_direct_prop->curr_list_node , & (list_node_direct_prop->list_direct_prop->list) , struct ListNode , node ) ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "after ZlangInvokeFunction_list_node_TravelPrev , prev[%p] curr[%p] next[%p]" , list_node_direct_prop->prev_list_node , list_node_direct_prop->curr_list_node , list_node_direct_prop->next_list_node )
	
	if( list_node_direct_prop->curr_list_node == NULL )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return 1;
	}
	
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_node_TravelPrev;
int ZlangInvokeFunction_list_node_TravelPrev( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = list_node_TravelPrev( rt , obj ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_list_node_IsTravelOver list_node_IsTravelOver;
int list_node_IsTravelOver( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = GetObjectDirectProperty(obj) ;
	
	if( list_node_direct_prop->curr_list_node == NULL )
		return 1;
	else
		return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_node_IsTravelOver;
int ZlangInvokeFunction_list_node_IsTravelOver( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = list_node_IsTravelOver( rt , obj ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	}
	else
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
	}
	
	return 0;
}

ZlangDirectFunction_list_node_Remove list_node_Remove;
int list_node_Remove( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	if( list_node_direct_prop->curr_list_node == NULL )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return -1;
	}
	
	list_del( & (list_node_direct_prop->curr_list_node->node) );
	DestroyObject( rt , list_node_direct_prop->curr_list_node->member );
	ZLFREE( list_node_direct_prop->curr_list_node );
	
	list_node_direct_prop->list_direct_prop->list_length--;
	
	if( list_node_direct_prop->next_list_node )
	{
		list_node_direct_prop->curr_list_node = list_node_direct_prop->next_list_node ;
		list_node_direct_prop->next_list_node = list_next_entry_or_null( list_node_direct_prop->curr_list_node , & (list_node_direct_prop->list_direct_prop->list) , struct ListNode , node ) ;
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return 1;
	}
	else
	{
		list_node_direct_prop->curr_list_node = list_node_direct_prop->prev_list_node ;
		list_node_direct_prop->prev_list_node = list_prev_entry_or_null( list_node_direct_prop->curr_list_node , & (list_node_direct_prop->list_direct_prop->list) , struct ListNode , node ) ;
		list_node_direct_prop->next_list_node = NULL ;
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return -1;
	}
}

ZlangInvokeFunction ZlangInvokeFunction_list_node_Remove;
int ZlangInvokeFunction_list_node_Remove( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int			nret = 0 ;
	
	nret = list_node_Remove( rt , obj ) ;
	if( nret == 0 )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_list_node_GetMember list_node_GetMember;
int list_node_GetMember( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **element )
{
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*member = NULL ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	if( list_node_direct_prop->curr_list_node == NULL )
	{
		if( element )
			(*element) = NULL ;
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return 1;
	}
	
	member = list_node_direct_prop->curr_list_node->member ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "member[%p]" , member )
	
	if( element )
		(*element) = member ;
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_node_GetMember;
int ZlangInvokeFunction_list_node_GetMember( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*member = NULL ;
	int					nret = 0 ;
	
	nret = list_node_GetMember( rt , obj , & member ) ;
	if( nret )
	{
		UnreferObject( rt , out1 );
		return 0;
	}
	
	nret = ReferObject( rt , out1 , member ) ;
	if( nret )
	{
		UnreferObject( rt , out1 );
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_REFER_OBJECT_FAILED );
	}
	
	return 0;
}

ZlangCreateDirectPropertyFunction ZlangCreateDirectProperty_list_node;
void *ZlangCreateDirectProperty_list_node( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = NULL ;
	
	list_node_direct_prop = (struct ZlangDirectProperty_list_node *)ZLMALLOC( sizeof(struct ZlangDirectProperty_list_node) ) ;
	if( list_node_direct_prop == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for entity" )
		return NULL;
	}
	memset( list_node_direct_prop , 0x00 , sizeof(struct ZlangDirectProperty_list_node) );
	
	return (struct ZlangEntity *)list_node_direct_prop;
}

ZlangDestroyDirectPropertyFunction ZlangDestroyDirectProperty_list_node;
void ZlangDestroyDirectProperty_list_node( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = GetObjectDirectProperty(obj) ;
	
	ZLFREE( list_node_direct_prop );
	
	return;
}

ZlangFromDataPtrFunction ZlangFromDataPtr_list_node;
int ZlangFromDataPtr_list_node( struct ZlangRuntime *rt , struct ZlangObject *obj , void *value_ptr , int32_t value_len )
{
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = GetObjectDirectProperty(obj) ;
	
	memcpy( list_node_direct_prop , value_ptr , value_len );
	
	return 0;
}

ZlangGetDataPtrFunction ZlangGetDataPtr_list_node;
int ZlangGetDataPtr_list_node( struct ZlangRuntime *rt , struct ZlangObject *obj , void **value_ptr , int32_t *value_len )
{
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = GetObjectDirectProperty(obj) ;
	
	if( value_ptr )
		(*value_ptr) = list_node_direct_prop ;
	if( value_len )
		(*value_len) = sizeof(struct ZlangDirectProperty_list_node) ;
	return 0;
}

ZlangSummarizeDirectPropertySizeFunction ZlangSummarizeDirectPropertySize_list_node;
void ZlangSummarizeDirectPropertySize_list_node( struct ZlangRuntime *rt , struct ZlangObject *obj , size_t *summarized_obj_size , size_t *summarized_direct_prop_size )
{
	SUMMARIZE_SIZE( summarized_direct_prop_size , sizeof(struct ZlangDirectProperty_list_node) )
	return;
}

static struct ZlangDirectFunctions direct_funcs_list_node =
	{
		ZLANG_OBJECT_list_node ,
		
		ZlangCreateDirectProperty_list_node ,
		ZlangDestroyDirectProperty_list_node ,
		
		NULL ,
		NULL ,
		ZlangFromDataPtr_list_node ,
		ZlangGetDataPtr_list_node ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		ZlangSummarizeDirectPropertySize_list_node ,
	} ;

ZlangImportObjectFunction ZlangImportObject_list_node;
struct ZlangObject *ZlangImportObject_list_node( struct ZlangRuntime *rt )
{
	struct ZlangObject	*obj = NULL ;
	struct ZlangFunction	*func = NULL ;
	int			nret = 0 ;
	
	nret = ImportObject( rt , & obj , ZLANG_OBJECT_list_node , & direct_funcs_list_node , sizeof(struct ZlangDirectFunctions) , NULL ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LINK_FUNC_TO_ENTITY , "import object to global objects heap" )
		DestroyObject( rt , obj );
		return NULL;
	}
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_node_TravelNext , ZLANG_OBJECT_bool , "TravelNext" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_node_TravelPrev , ZLANG_OBJECT_bool , "TravelPrev" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_node_IsTravelOver , ZLANG_OBJECT_bool , "IsTravelOver" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_node_Remove , ZLANG_OBJECT_bool , "Remove" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_node_GetMember , ZLANG_OBJECT_object , "GetMember" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	SetRuntimeFunction_list_node_TravelNext( rt , list_node_TravelNext );
	SetRuntimeFunction_list_node_TravelPrev( rt , list_node_TravelPrev );
	SetRuntimeFunction_list_node_IsTravelOver( rt , list_node_IsTravelOver );
	SetRuntimeFunction_list_node_Remove( rt , list_node_Remove );
	SetRuntimeFunction_list_node_GetMember( rt , list_node_GetMember );
	
	return obj ;
}

ZlangDirectFunction_list_AddHead list_AddHead;
int list_AddHead( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *element , struct ZlangObject **add )
{
	struct ZlangDirectProperty_list		*list_direct_prop = GetObjectDirectProperty(obj) ;
	char					*ext_obj_name = NULL ;
	char					*clone_obj_name = NULL ;
	struct ListNode				*list_node = NULL ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	ext_obj_name = GetObjectEmbellishName( obj ) ;
	clone_obj_name = GetCloneObjectName( element ) ;
	if( ext_obj_name )
	{
		if( clone_obj_name == NULL || STRCMP( ext_obj_name , != , clone_obj_name ) )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "object type not matched" )
			IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
			return -ZLANG_ERROR_TYPE_OF_OBJECT_NOT_MATCHED;
		}
	}
	
	list_node = (struct ListNode *)ZLMALLOC( sizeof(struct ListNode) ) ;
	if( list_node == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for list node" )
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return ZLANG_ERROR_ALLOC;
	}
	memset( list_node , 0x00 , sizeof(struct ListNode) );
	
	list_node->member = AllocObject( rt ) ;
	if( list_node->member == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for object" )
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return ZLANG_ERROR_ALLOC;
	}
	
	nret = ReferObject( rt , list_node->member , element ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ReferObject failed[%d]" , nret )
		DestroyObject( rt , list_node->member );
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return nret;
	}
	
	nret = SetObjectName( rt , list_node->member , GetObjectName(element) ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "SetObjectName failed[%d]" , nret )
		DestroyObject( rt , list_node->member );
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return nret;
	}
	
	TEST_RUNTIME_DEBUG(rt)
	{
		PRINT_TABS(rt) printf("add head list_node->member , "); DebugPrintObject(rt,list_node->member); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
	}
	LIST_ADD( & (list_node->node) , & (list_direct_prop->list) );
	
	list_direct_prop->list_length++;
	
	if( add )
		(*add) = list_node->member ;
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_AddHead_object;
int ZlangInvokeFunction_list_AddHead_object( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject		*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int				nret = 0 ;
	
	nret = list_AddHead( rt , obj , in1 , NULL ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		if( nret < 0 )
			return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
		else
			return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_list_AddTail list_AddTail;
int list_AddTail( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *element , struct ZlangObject **add )
{
	struct ZlangDirectProperty_list	*list_direct_prop = GetObjectDirectProperty(obj) ;
	char				*ext_obj_name = NULL ;
	char				*clone_obj_name = NULL ;
	struct ListNode			*list_node = NULL ;
	int				nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	ext_obj_name = GetObjectEmbellishName( obj ) ;
	clone_obj_name = GetCloneObjectName( element ) ;
	if( ext_obj_name )
	{
		if( clone_obj_name == NULL || STRCMP( ext_obj_name , != , clone_obj_name ) )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "object type not matched" )
			IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
			return -ZLANG_ERROR_TYPE_OF_OBJECT_NOT_MATCHED;
		}
	}
	
	list_node = (struct ListNode *)ZLMALLOC( sizeof(struct ListNode) ) ;
	if( list_node == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for list node" )
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return ZLANG_ERROR_ALLOC;
	}
	memset( list_node , 0x00 , sizeof(struct ListNode) );
	
	list_node->member = AllocObject( rt ) ;
	if( list_node->member == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for object" )
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return ZLANG_ERROR_ALLOC;
	}
	
	nret = ReferObject( rt , list_node->member , element ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ReferObject failed[%d]" , nret )
		DestroyObject( rt , list_node->member );
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return nret;
	}
	
	nret = SetObjectName( rt , list_node->member , GetObjectName(element) ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "SetObjectName failed[%d]" , nret )
		DestroyObject( rt , list_node->member );
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return nret;
	}
	
	TEST_RUNTIME_DEBUG(rt)
	{
		PRINT_TABS(rt) printf("add tail list_node->member , "); DebugPrintObject(rt,list_node->member); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
	}
	list_add_tail( & (list_node->node) , & (list_direct_prop->list) );
	
	list_direct_prop->list_length++;
	
	if( add )
		(*add) = list_node->member ;
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_AddTail_object;
int ZlangInvokeFunction_list_AddTail_object( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject		*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int				nret = 0 ;
	
	nret = list_AddTail( rt , obj , in1 , NULL ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		if( nret < 0 )
			return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
		else
			return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangDirectFunction_list_RemoveAll list_RemoveAll;
int list_RemoveAll( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list	*list_direct_prop = GetObjectDirectProperty(obj) ;
	struct ListNode			*curr_node = NULL ;
	struct ListNode			*next_node = NULL ;
	int				nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	list_for_each_entry_safe( curr_node , next_node , & (list_direct_prop->list) , struct ListNode , node )
	{
		list_del( & (curr_node->node) );
		
		DestroyObject( rt , curr_node->member );
		ZLFREE( curr_node );
	}
	
	list_direct_prop->list_length = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_RemoveAll;
int ZlangInvokeFunction_list_RemoveAll( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	int				nret = 0 ;
	
	nret = list_RemoveAll( rt , obj ) ;
	if( nret )
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	
	return 0;
}

ZlangDirectFunction_list_GetHead list_GetHead;
int list_GetHead( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **list_node )
{
	struct ZlangDirectProperty_list		*list_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*list_node_obj = NULL ;
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = NULL ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	if( list_node && (*list_node) )
	{
		list_node_obj = (*list_node) ;
	}
	else
	{
		list_node_obj = CloneListNodeObjectInTmpStack( rt , NULL ) ;
		if( list_node_obj == NULL )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
			return -1;
		}
	}
	list_node_direct_prop = GetObjectDirectProperty( list_node_obj ) ;
	
	list_node_direct_prop->curr_list_node = list_first_entry_or_null( & (list_direct_prop->list) , struct ListNode , node ) ;
	if( list_node_direct_prop->curr_list_node == NULL )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return -1;
	}
	list_node_direct_prop->prev_list_node = NULL ;
	list_node_direct_prop->next_list_node = list_next_entry_or_null( list_node_direct_prop->curr_list_node , & (list_direct_prop->list) , struct ListNode , node ) ;
	list_node_direct_prop->list_direct_prop = list_direct_prop ;
	
	if( list_node && (*list_node) == NULL )
		(*list_node) = list_node_obj ;
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_GetHead;
int ZlangInvokeFunction_list_GetHead( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*list_node_obj = NULL ;
	int			nret = 0 ;
	
	nret = list_GetHead( rt , obj , & list_node_obj ) ;
	if( nret )
	{
		UnreferObject( rt , out1 );
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	}
	
	ReferObject( rt , out1 , list_node_obj ) ;
	
	return 0;
}

ZlangDirectFunction_list_GetHead list_GetTail;
int list_GetTail( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **list_node )
{
	struct ZlangDirectProperty_list		*list_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*list_node_obj = NULL ;
	struct ZlangDirectProperty_list_node	*list_node_direct_prop = NULL ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	if( list_node && (*list_node) )
	{
		list_node_obj = (*list_node) ;
	}
	else
	{
		list_node_obj = CloneListNodeObjectInTmpStack( rt , NULL ) ;
		if( list_node_obj == NULL )
		{
			IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
			return -1;
		}
	}
	list_node_direct_prop = GetObjectDirectProperty( list_node_obj ) ;
	
	list_node_direct_prop->curr_list_node = list_last_entry_or_null( & (list_direct_prop->list) , struct ListNode , node ) ;
	if( list_node_direct_prop->curr_list_node == NULL )
	{
		IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
		return -1;
	}
	list_node_direct_prop->prev_list_node = list_prev_entry_or_null( list_node_direct_prop->curr_list_node , & (list_direct_prop->list) , struct ListNode , node ) ;
	list_node_direct_prop->next_list_node = NULL ;
	list_node_direct_prop->list_direct_prop = list_direct_prop ;
	
	if( list_node && (*list_node) == NULL )
		(*list_node) = list_node_obj ;
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_GetTail;
int ZlangInvokeFunction_list_GetTail( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject	*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject	*list_node_obj = NULL ;
	int			nret = 0 ;
	
	nret = list_GetTail( rt , obj , & list_node_obj ) ;
	if( nret )
	{
		UnreferObject( rt , out1 );
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	}
	
	ReferObject( rt , out1 , list_node_obj ) ;
	
	return 0;
}

ZlangDirectFunction_list_Length list_Length;
int list_Length( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *list_length )
{
	struct ZlangDirectProperty_list		*list_direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	(*list_length) = list_direct_prop->list_length ;
	
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_Length;
int ZlangInvokeFunction_list_Length( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t					list_length ;
	int					nret = 0 ;
	
	nret = list_Length( rt , obj , & list_length );
	if( nret )
	{
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	}
	
	CallRuntimeFunction_int_SetIntValue( rt , out1 , list_length );
	return 0;
}

ZlangDirectFunction_list_IsEmpty list_IsEmpty;
int list_IsEmpty( struct ZlangRuntime *rt , struct ZlangObject *obj , unsigned char *b )
{
	struct ZlangDirectProperty_list		*list_direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	if( list_direct_prop->list_length == 0 )
		(*b) = TRUE ;
	else
		(*b) = FALSE ;
	
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_IsEmpty;
int ZlangInvokeFunction_list_IsEmpty( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	unsigned char				b ;
	int					nret = 0 ;
	
	nret = list_IsEmpty( rt , obj , & b ) ;
	if( nret )
	{
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , b );
	
	return 0;
}

ZlangDirectFunction_list_IsEmpty list_IsNotEmpty;
int list_IsNotEmpty( struct ZlangRuntime *rt , struct ZlangObject *obj , unsigned char *b )
{
	struct ZlangDirectProperty_list		*list_direct_prop = GetObjectDirectProperty(obj) ;
	int					nret = 0 ;
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	if( list_direct_prop->list_length != 0 )
		(*b) = TRUE ;
	else
		(*b) = FALSE ;
	
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_list_IsNotEmpty;
int ZlangInvokeFunction_list_IsNotEmpty( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	unsigned char				b ;
	int					nret = 0 ;
	
	nret = list_IsEmpty( rt , obj , & b ) ;
	if( nret )
	{
		return ThrowFatalException( rt , nret , EXCEPTION_MESSAGE_GENERAL_ERROR );
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , b );
	
	return 0;
}

#define OVECCOUNT	100*3

ZlangInvokeFunction ZlangInvokeFunction_BatchRegexpMatchReserved_string;
int ZlangInvokeFunction_BatchRegexpMatchReserved_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list		*list_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	struct ListNode				*curr_node = NULL ;
	struct ListNode				*next_node = NULL ;
	char					*str = NULL ;
	int32_t					str_len ;
	char					*pattern = NULL ;
	int32_t					pattern_len ;
	pcre					*pattern_re = NULL ;
	const char				*errptr = NULL ;
	int					erroffset ;
	int					ovector[ OVECCOUNT ] = { 0 } ;
	int					match_count ;
	int					total_match_count ;
	int					nret = 0 ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & pattern , & pattern_len );
	
	pattern_re = pcre_compile( pattern , 0 , & errptr , & erroffset , NULL ) ;
	if( pattern_re == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] failed" , pattern )
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] ok" , pattern )
	}
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	total_match_count = 0 ;
	list_for_each_entry_safe( curr_node , next_node , & (list_direct_prop->list) , struct ListNode , node )
	{
		if( ! IsTypeOf( rt , curr_node->member , GetStringObjectInRuntimeObjectsHeap(rt) ) )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "member type is not string" )
			pcre_free( pattern_re );
			IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
			CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
			return ThrowErrorException( rt , ZLANG_ERROR_OBJECT_TYPE_INVALID , EXCEPTION_MESSAGE_OBJECT_TYPE_INVALID );
		}

		CallRuntimeFunction_string_GetStringValue( rt , curr_node->member , & str , & str_len );

		match_count = pcre_exec( pattern_re , NULL , str , str_len , 0 , 0 , ovector , OVECCOUNT ) ;
		if( match_count == 0 || match_count == PCRE_ERROR_NOMATCH )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] not matched" , str_len,str )
			list_del( & (curr_node->node) );
			DestroyObject( rt , curr_node->member );
			ZLFREE( curr_node );
			list_direct_prop->list_length--;
		}
		else if( match_count < 0 )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] failed[%d]" , str_len,str , match_count )
			pcre_free( pattern_re );
			IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
			CallRuntimeFunction_int_SetIntValue( rt , out1 , -2 );
			return ThrowErrorException( rt , ZLANG_ERROR_INVOKE_METHOD_RETURN , "pcre_exec failed" );
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] matched" , str_len,str )
			total_match_count++;
		}
	}
	
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	
	pcre_free( pattern_re );

	CallRuntimeFunction_int_SetIntValue( rt , out1 , total_match_count );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_BatchRegexpMatchReserved_string_string;
int ZlangInvokeFunction_BatchRegexpMatchReserved_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list		*list_direct_prop = GetObjectDirectProperty(obj) ;
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	struct ListNode				*curr_node = NULL ;
	struct ListNode				*next_node = NULL ;
	char					*str = NULL ;
	int32_t					str_len ;
	char					*prop_name = NULL ;
	struct ZlangObject			*prop_obj = NULL ;
	char					*pattern = NULL ;
	int32_t					pattern_len ;
	pcre					*pattern_re = NULL ;
	const char				*errptr = NULL ;
	int					erroffset ;
	int					ovector[ OVECCOUNT ] = { 0 } ;
	int					match_count ;
	int					total_match_count ;
	int					nret = 0 ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & prop_name , NULL );
	CallRuntimeFunction_string_GetStringValue( rt , in2 , & pattern , & pattern_len );
	
	pattern_re = pcre_compile( pattern , 0 , & errptr , & erroffset , NULL ) ;
	if( pattern_re == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] failed" , pattern )
		CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
		return 0;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_compile[%s] ok" , pattern )
	}
	
	IF_ATOMIC_OBJECT_THEN_LOCK( obj )
	
	total_match_count = 0 ;
	list_for_each_entry_safe( curr_node , next_node , & (list_direct_prop->list) , struct ListNode , node )
	{
		prop_obj = QueryPropertyInObjectByPropertyName( rt , curr_node->member , prop_name ) ;
		if( prop_obj == NULL )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "property not found" )
			pcre_free( pattern_re );
			IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
			CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
			return ThrowErrorException( rt , ZLANG_ERROR_PROPERTY_NOT_FOUND , EXCEPTION_MESSAGE_PROPERTY_NOT_FOUND );
		}

		if( ! IsTypeOf( rt , prop_obj , GetStringObjectInRuntimeObjectsHeap(rt) ) )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "member type is not string" )
			pcre_free( pattern_re );
			IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
			CallRuntimeFunction_int_SetIntValue( rt , out1 , -1 );
			return ThrowErrorException( rt , ZLANG_ERROR_OBJECT_TYPE_INVALID , EXCEPTION_MESSAGE_OBJECT_TYPE_INVALID );
		}

		CallRuntimeFunction_string_GetStringValue( rt , prop_obj , & str , & str_len );

		match_count = pcre_exec( pattern_re , NULL , str , str_len , 0 , 0 , ovector , OVECCOUNT ) ;
		if( match_count == 0 || match_count == PCRE_ERROR_NOMATCH )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] not matched" , str_len,str )
			list_del( & (curr_node->node) );
			DestroyObject( rt , curr_node->member );
			ZLFREE( curr_node );
			list_direct_prop->list_length--;
		}
		else if( match_count < 0 )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] failed[%d]" , str_len,str , match_count )
			pcre_free( pattern_re );
			IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
			CallRuntimeFunction_int_SetIntValue( rt , out1 , -2 );
			return ThrowErrorException( rt , ZLANG_ERROR_INVOKE_METHOD_RETURN , "pcre_exec failed" );
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "pcre_exec[%.*s] matched" , str_len,str )
			total_match_count++;
		}
	}
	
	IF_ATOMIC_OBJECT_THEN_UNLOCK( obj );
	
	pcre_free( pattern_re );

	CallRuntimeFunction_int_SetIntValue( rt , out1 , total_match_count );
	return 0;
}

ZlangCreateDirectPropertyFunction ZlangCreateDirectProperty_list;
void *ZlangCreateDirectProperty_list( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list	*list_direct_prop = NULL ;
	
	list_direct_prop = (struct ZlangDirectProperty_list *)ZLMALLOC( sizeof(struct ZlangDirectProperty_list) ) ;
	if( list_direct_prop == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for entity" )
		return NULL;
	}
	memset( list_direct_prop , 0x00 , sizeof(struct ZlangDirectProperty_list) );
	
	INIT_LIST_HEAD( & (list_direct_prop->list) );
	
	
	return (struct ZlangEntity *)list_direct_prop;
}

ZlangDestroyDirectPropertyFunction ZlangDestroyDirectProperty_list;
void ZlangDestroyDirectProperty_list( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_list	*list_direct_prop = GetObjectDirectProperty(obj) ;
	struct ListNode			*curr_node = NULL ;
	struct ListNode			*next_node = NULL ;
	
	list_for_each_entry_safe( curr_node , next_node , & (list_direct_prop->list) , struct ListNode , node )
	{
		list_del( & (curr_node->node) );
		
		DestroyObject( rt , curr_node->member );
		ZLFREE( curr_node );
	}
	
	ZLFREE( list_direct_prop );
	
	return;
}

ZlangSummarizeDirectPropertySizeFunction ZlangSummarizeDirectPropertySize_list;
void ZlangSummarizeDirectPropertySize_list( struct ZlangRuntime *rt , struct ZlangObject *obj , size_t *summarized_obj_size , size_t *summarized_direct_prop_size )
{
	struct ZlangDirectProperty_list	*list_direct_prop = GetObjectDirectProperty(obj) ;
	struct ListNode			*list_node = NULL ;
	
	list_for_each_entry( list_node , & (list_direct_prop->list) , struct ListNode , node )
	{
		SummarizeObjectSize( rt , list_node->member , summarized_obj_size , summarized_direct_prop_size );
	}
	
	SUMMARIZE_SIZE( summarized_direct_prop_size , sizeof(struct ZlangDirectProperty_list) )
	
	return;
}

static struct ZlangDirectFunctions direct_funcs_list =
	{
		ZLANG_OBJECT_list ,
		
		ZlangCreateDirectProperty_list ,
		ZlangDestroyDirectProperty_list ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		NULL ,
		
		ZlangSummarizeDirectPropertySize_list ,
	} ;

ZlangImportObjectFunction ZlangImportObject_list;
struct ZlangObject *ZlangImportObject_list( struct ZlangRuntime *rt )
{
	struct ZlangObject	*obj = NULL ;
	struct ZlangFunction	*func = NULL ;
	int			nret = 0 ;
	
	nret = ImportObject( rt , & obj , ZLANG_OBJECT_list , & direct_funcs_list , sizeof(struct ZlangDirectFunctions) , NULL ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LINK_FUNC_TO_ENTITY , "import object to global objects heap" )
		return NULL;
	}
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_AddHead_object , ZLANG_OBJECT_bool , "AddHead" , ZLANG_OBJECT_object,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_AddHead_object , ZLANG_OBJECT_bool , "AddHead" , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_AddHead_object , ZLANG_OBJECT_bool , "AddHead" , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_AddTail_object , ZLANG_OBJECT_bool , "AddTail" , ZLANG_OBJECT_object,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_AddTail_object , ZLANG_OBJECT_bool , "AddTail" , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_AddTail_object , ZLANG_OBJECT_bool , "AddTail" , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_RemoveAll , ZLANG_OBJECT_void , "RemoveAll" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_GetHead , ZLANG_OBJECT_list_node , "GetHead" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_GetTail , ZLANG_OBJECT_list_node , "GetTail" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_Length , ZLANG_OBJECT_int , "Length" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_IsEmpty , ZLANG_OBJECT_bool , "IsEmpty" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_list_IsNotEmpty , ZLANG_OBJECT_bool , "IsNotEmpty" , NULL ) ;
	if( func == NULL )
		return NULL;
	
	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_BatchRegexpMatchReserved_string , ZLANG_OBJECT_int , "BatchRegexpMatchReserved" , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;

	func = AddFunctionAndParametersInObject( rt , obj , ZlangInvokeFunction_BatchRegexpMatchReserved_string_string , ZLANG_OBJECT_int , "BatchRegexpMatchReserved" , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;

	SetRuntimeFunction_list_AddHead( rt , list_AddHead );
	SetRuntimeFunction_list_AddTail( rt , list_AddTail );
	SetRuntimeFunction_list_RemoveAll( rt , list_RemoveAll );
	SetRuntimeFunction_list_GetHead( rt , list_GetHead );
	SetRuntimeFunction_list_GetTail( rt , list_GetTail );
	SetRuntimeFunction_list_Length( rt , list_Length );
	SetRuntimeFunction_list_IsEmpty( rt , list_IsEmpty );
	SetRuntimeFunction_list_IsNotEmpty( rt , list_IsNotEmpty );
	
	return obj ;
}

